package com.tan.lbs.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import com.tan.lbs.dao.GameDAO;
import com.tan.lbs.dao.MediaDAO;
import com.tan.lbs.dao.impl.GameDAOImpl;
import com.tan.lbs.dao.impl.MediaDAOImpl;
import com.tan.lbs.entity.Game;
import com.tan.lbs.entity.GameHeader;
import com.tan.lbs.entity.Media;
import com.tan.lbs.service.GameService;
import com.tan.lbs.util.dbsql2xml;

/**
 * 
 * Copyright by Zhensheng Tan only for Final Year Project Use. Class
 * description:
 * 
 * @author Zhensheng Tan
 * 
 */
public class GameServiceImpl implements GameService {

	private GameDAO gameDAO;
	private MediaDAO mediaDAO;

	public static String GAME_PUBLISH_DIRECTORY = "/gameFiles/";

	public GameServiceImpl() {
		gameDAO = new GameDAOImpl();
		mediaDAO = new MediaDAOImpl();
	}

	@Override
	public Game loadGameDetails(String gameID) {
		return gameDAO.readByID(gameID);
	}

	@Override
	public String createNewGame(Game game) {
		game.setDesignStatus("e");
		return gameDAO.create(game);
	}

	@Override
	public ArrayList<GameHeader> retrieveGameList(String designerID) {

		ArrayList<Game> games = gameDAO.searchByDesigner(designerID);
		ArrayList<GameHeader> gHeaders = new ArrayList<GameHeader>();
		for (Game game : games) {
			GameHeader gHeader = new GameHeader();
			gHeader.setGameID(game.getGameID());
			gHeader.setGameName(game.getGameName());
			gHeaders.add(gHeader);
		}
		return gHeaders;
	}

	@Override
	public void modifyGameDetails(Game game) {
		Game oldGame = gameDAO.readByID(game.getGameID());
		game.setIconID(oldGame.getIconID());
		game.setGameCoverID(oldGame.getGameCoverID());
		gameDAO.update(game);
	}

	@Override
	public int publishGame(String gameID, HttpServletRequest request,
			ServletContext context) {
		if (request != null) {
			String realPath = request.getSession().getServletContext()
					.getRealPath("/");
			String basePath = realPath + "gameFiles/";
			String createPath = basePath + gameID + "/";
			File createGameDir = new File(createPath);

			removeDirectory(createGameDir);
			createGameDir.mkdirs();

			List<String> tables = new ArrayList<String>();
			tables.add("item");
			tables.add("npc");
			tables.add("gametrigger");
			tables.add("gamecondition");
			tables.add("quest");
			tables.add("dialognode");
			tables.add("dialognodeorder");
			tables.add("objlocation");
			tables.add("game");

			for (String tableName : tables) {
				dbsql2xml export = new dbsql2xml(gameID, tableName, basePath
						+ "mapping/" + tableName + "Mapping.xml", basePath
						+ "mapping/dbsql2xml.xsd", "$gv00", gameID, createPath
						+ tableName + ".xml");

				try {
					export.doExportIntoFile();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			try {

				ArrayList<Media> medias = mediaDAO.searchByGame(gameID);
				for (Media media : medias) {
					String path = realPath + "uploadFiles/" + media.getMediaID() + "."
							+ media.getType();
					File fromFile = new File(path);
					File toFile = new File(createPath + media.getMediaID() + "."
							+ media.getType());
					if(!toFile.exists()) toFile.createNewFile();
					FileOutputStream out = new FileOutputStream(toFile);
					FileInputStream in = new FileInputStream(fromFile);
					byte[]   buff   =   new   byte[1024];
					int   readed   =   -1;
					while((readed   =   in.read(buff))   >   0) {
					    out.write(buff,   0,   readed); 
					}
					out.flush();
					out.close();
					in.close();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		return 0;
	}
	
	private boolean removeDirectory(File directory) {
		  if (directory == null)
		    return false;
		  if (!directory.exists())
		    return true;
		  if (!directory.isDirectory())
		    return false;

		  String[] list = directory.list();

		  if (list != null) {
		    for (int i = 0; i < list.length; i++) {
		      File entry = new File(directory, list[i]);
		      if (entry.isDirectory())
		      {
		        if (!removeDirectory(entry))
		          return false;
		      }
		      else
		      {
		        if (!entry.delete())
		          return false;
		      }
		    }
		  }
		  return directory.delete();
		}

}
